/*
 * Author: 李波(Edwin Lee)
 * Date: 2024-08-05 15:49:31
 * FilePath: /mprpc/example/callee/userservice.cc
 * LastEditTime: 2024-08-19 06:46:22
 * version: 1.0
 * Description: UserService原来是一个本地服务，提供了两个进程内的本地方法，Login和GetFriendLists，
 * 现在我们把它变为rpc服务的callee
 */
#include "user.pb.h"
#include "mprpcapplication.h"
#include "rpcprovider.h"
#include <iostream>
#include <string>

// 使用在rpc服务发布端（rpc服务提供者）
class UserService : public fixbug::UserServiceRpc
{
public:
    bool Login(std::string name, std::string pwd)
    {
        std::cout << "doing local service:Login" << std::endl;
        std::cout << "name:" << name << "pwd" <<std::endl;
        return true;
    }

    bool Register(uint32_t id, std::string name, std::string pwd)
    {
        std::cout << "doing local service:Register" << std::endl;
        std::cout << "id: " << id << " name:" << name << "pwd" << pwd << std::endl;
        return true;  
    }

    // 重写基类UserServiceRpc的虚函数，下面这些方法都是框架直接调用的
    // 1.caller ===> Login(LoginRequest) ==> muduo ==> callee
    // 2.callee ===> Login(LoginRequest) ==>交到下面重写的这个Login方法上
    void Login(::google::protobuf::RpcController* controller,
                       const ::fixbug::LoginRequest* request,
                       ::fixbug::LoginResponse* response,
                       ::google::protobuf::Closure* done)
    {
        // 框架给业务上报了请求参数LoginRequest，应用获取相应数据做本地业务
        std::string name = request->name();
        std::string pwd = request->pwd();

        // 做本地业务
        bool login_result = Login(name,pwd);

        // 把响应写入
        fixbug::ResultCode* code = response->mutable_result();
        code->set_errcode(0);
        code->set_errmsg("");
        response->set_sucess(login_result);

        // 执行回调操作 执行相应对象数据的序列化和网络发送（都是由框架完成）
        done->Run();
    }

    void Register(::google::protobuf::RpcController* controller,
                       const ::fixbug::RegisterRequest* request,
                       ::fixbug::RegisterResponse* response,
                       ::google::protobuf::Closure* done)
    {
        uint32_t id = request->id();
        std::string name = request->name();
        std::string pwd = request->pwd();

        // 做本地业务
        bool register_result = Register(id,name,pwd);

        // 把响应写入
        fixbug::ResultCode* code = response->mutable_result();
        code->set_errcode(0);
        code->set_errmsg("");
        response->set_sucess(register_result);

        // 执行回调操作 执行相应对象数据的序列化和网络发送（都是由框架完成）
        done->Run();
    }
};

// 框架的使用
int main(int argc, char** argv)
{
    // 初始化框架
    std::cout << "init begin"<<std::endl;
    MprpcApplication::init(argc,argv);

    // provider是一个rpc网络服务对象。把UserService对象发布到rpc节点上
    RpcProvider provider;
    provider.NotifyService(new UserService());

    // 启动一个rpc服务发布节点 Run以后，进程进入阻塞状态，等待远程的rpc调用请求
    provider.Run();

    return 0;
}